package com.example.demo.controller;

import com.example.demo.PO.Lesson;
import com.example.demo.PO.Major;
import com.example.demo.PO.Student;
import com.example.demo.util.Counter;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.util.*;

@RestController
public class UserController {


    private List<Map<String,Object>> accounts;
    private List<Lesson> allLesson;

    private Map<String,Student> studentInfo;
    private Map<String,Major> majorDetail;
    private String currentUser = "23120001";
    private String currentMajor = "软件工程";


    @GetMapping("/getAllCharacter")
    public ResponseEntity<List<Map<String,Object>>> getAllCharacter(){
        if(this.accounts == null) this.accounts = transferJsonToList( "src/main/java/com/example/demo/JSON/account.json");
        return ResponseEntity.ok(this.accounts);
    }
    @GetMapping("/login")
    public ResponseEntity<String> login(@RequestParam("username") String username, @RequestParam("password") String password){

        if(this.accounts == null) this.accounts = transferJsonToList( "src/main/java/com/example/demo/JSON/account.json");
        if(this.allLesson == null) this.allLesson = transferLesson("src/main/java/com/example/demo/JSON/AllLessonWithKey.json");
        if(this.studentInfo == null) this.studentInfo = transferStudent("src/main/java/com/example/demo/JSON/studentInfo.json");
        if(this.majorDetail == null) this.majorDetail = transferMajor("src/main/java/com/example/demo/JSON/majorDetail.json");
        for (Map<String, Object> account : accounts) {
            if (username.equals(account.get("username")) && password.equals(account.get("password"))) {
                this.currentUser = account.get("name").toString();
                if(studentInfo.get(username).getMajor() != null){
                    this.currentMajor = studentInfo.get(username).getMajor();
                }else{
                    this.currentMajor = studentInfo.get(username).getMajor_categories();

                }

                return ResponseEntity.ok(account.get("name").toString());
            }
        }

        // 用户名或密码错误，返回错误响应
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误");
    }

   @GetMapping("/studentInfo")
   public ResponseEntity<?> getStudentInfo(@RequestParam("studentID") String studentID){
       if(this.studentInfo == null) this.studentInfo = transferStudent("src/main/java/com/example/demo/JSON/studentInfo.json");
       countCreditComposition(studentID);
       Student student = this.studentInfo.get(studentID);

       return ResponseEntity.ok(student);
   }

    /**
     * 选課页面按分类展示課程列表，無推荐，其中通識課号是确定的，公选課不确定全不全。另外体育課經典閱讀等等無從獲取
     * @param category
     * @return
     */
   @GetMapping("/getCourseByCategory")
   public ResponseEntity<?> getCoursesByCategory(@RequestParam("category")String category){
        List<Lesson> courseList = new ArrayList<>();
        if(category.equals("全部课程")){
            return ResponseEntity.ok(this.allLesson);
        }else if(category.equals("通修核心课")){
            List<String> allRequiredCourse = majorDetail.get(this.currentMajor).get学分构成().get通识通修().get通修课程().get课程列表();
            allRequiredCourse.addAll(majorDetail.get(this.currentMajor).get学分构成().get专业核心课程().get课程列表());
            for(String course1 : allRequiredCourse){
                for(Lesson course2 :this.allLesson){
                    if(course1.equals(course2.get课程号())){
                        courseList.add(course2);
                    }
                }
            }
        }else if(category.equals("通识课")){
            for(Lesson course :this.allLesson){
                String courseNo = course.get课程号();
                if(courseNo.startsWith("002")|| courseNo.startsWith("003")|| courseNo.startsWith("004")|| courseNo.startsWith("005")|| courseNo.startsWith("37")|| courseNo.startsWith("500")){
                    courseList.add(course);
                }
            }

        }else if(category.equals("公选课")){
            for(Lesson course :this.allLesson){
                String courseNo = course.get课程号();
                if(courseNo.startsWith("61") || courseNo.startsWith("78")){
                    courseList.add(course);
                }
            }

        }else if(category.equals("跨专业课")){
            for(Lesson course :this.allLesson){
                String courseNo = course.get课程号();
                if(courseNo.startsWith("61") || courseNo.startsWith("78") || courseNo.startsWith("002")|| courseNo.startsWith("003")|| courseNo.startsWith("004")|| courseNo.startsWith("005")|| courseNo.startsWith("37")|| courseNo.startsWith("500")){
                    continue;
                }
                courseList.add(course);
            }
        }
        return ResponseEntity.ok(courseList);

   }
   @PostMapping("/chooseCourse")
   public ResponseEntity<?> chooseCourse(@RequestParam("studentID") String studentID, @RequestParam("courseID")String courseID){
       if(this.studentInfo.get(studentID).getStudy_situation().getChosen_course().contains(courseID)){
           return ResponseEntity.ok("該課程重複选择");
       }
       this.studentInfo.get(studentID).getStudy_situation().getChosen_course().add(courseID);
       return ResponseEntity.ok(studentInfo.get(studentID));
   }

    @PostMapping("/dropCourse")
    public ResponseEntity<?> dropCourse(@RequestParam("studentID") String studentID, @RequestParam("courseID")String courseID){
        if(!this.studentInfo.get(studentID).getStudy_situation().getChosen_course().contains(courseID)){
            return ResponseEntity.ok("你未选中該課程");
        }
        this.studentInfo.get(studentID).getStudy_situation().getChosen_course().remove(courseID);
        return ResponseEntity.ok(studentInfo.get(studentID));
    }

    /**
     * 計算已修完課程的學分构成，注意目前完全还沒考虑到專业是大类的情況，所以代碼都是寫死了getMajor，后面要記得改
     * @param studentID
     * @return
     */
    @GetMapping("/creditComposition")
    public ResponseEntity<?> countCreditComposition(@RequestParam("studentID") String studentID){
        Counter counter = new Counter();
        Student student = this.studentInfo.get(studentID);
        List<String> takenCourse = new ArrayList<>(student.getStudy_situation().getTaken_course());
        List<String> requiredGeneralCourse = this.majorDetail.get(student.getMajor()).get学分构成().get通识通修().get通修课程().get课程列表();
        List<String> requiredCoreCourse = this.majorDetail.get(student.getMajor()).get学分构成().get专业核心课程().get课程列表();
        Map<String,Double> creditComposition = counter.creditCompositionCounter(this.allLesson,requiredGeneralCourse,requiredCoreCourse,takenCourse);
        this.studentInfo.get(studentID).getStudy_situation().setCredit_composition(creditComposition);
        this.studentInfo.get(studentID).getStudy_situation().setGot_credit(creditComposition.get("全部"));
        return ResponseEntity.ok(this.studentInfo.get(studentID));
    }

    @GetMapping("/recommendCourses")
    public ResponseEntity<?> recommendCourses(@RequestParam("studentID") String studentID){
        List<Lesson> courseList = new ArrayList<>(this.allLesson);
        int eachKindRecommendNum = 5;//限制每类課程于開头的推荐數量
        List<Lesson> recommendCourse = new ArrayList<>();
        Counter counter = new Counter();
        Student student = this.studentInfo.get(studentID);
        List<String> takenCourse = new ArrayList<>(student.getStudy_situation().getTaken_course());
        List<String> chosenCourse = new ArrayList<>(student.getStudy_situation().getChosen_course());
        List<String> requiredGeneralCourse = this.majorDetail.get(student.getMajor()).get学分构成().get通识通修().get通修课程().get课程列表();
        List<String> requiredCoreCourse = this.majorDetail.get(student.getMajor()).get学分构成().get专业核心课程().get课程列表();
        Map<String,Double> creditComposition = counter.creditCompositionCounter(this.allLesson,requiredGeneralCourse,requiredCoreCourse,takenCourse);

        List<Lesson> courseListCopy = new ArrayList<>(courseList);
        takenCourse = new ArrayList<>(student.getStudy_situation().getTaken_course());
        for(int i = 0 ; i < takenCourse.size(); i++){
            String courseKey = takenCourse.get(i);
            String courseNo = courseKey.substring(0, 8);
            if(Character.isLetter(courseKey.toCharArray()[8])){
                courseNo += courseKey.toCharArray()[8];
            }
            takenCourse.set(i,courseNo);
        }

        for(int i = 0 ; i < chosenCourse.size(); i++){
            String courseKey = chosenCourse.get(i);
            String courseNo = courseKey.substring(0, 8);
            if(Character.isLetter(courseKey.toCharArray()[8])){
                courseNo += courseKey.toCharArray()[8];
            }
            chosenCourse.set(i,courseNo);
        }

        //把年級不合的移除
        for(Lesson lesson : courseListCopy){
            if(!lesson.get年级().contains(student.getAdmission_year().toString())){
                courseList.remove(lesson);
            }
        }
        //移除选过的課
        courseListCopy = new ArrayList<>(courseList);
        for(Lesson lesson : courseListCopy){
            if(takenCourse.contains(lesson.get课程号()) || chosenCourse.contains(lesson.get课程号())){
                courseList.remove(lesson);
            }
        }
        if(creditComposition.get("科学之光") == 0.0){
            Collections.shuffle(courseList);//隨机排列課程
            courseListCopy = new ArrayList<>(courseList);
            int recommendTime = 0;
            for(Lesson lesson:courseListCopy){
                if(lesson.get课程名().startsWith("“科学之光”")){
                    recommendCourse.add(lesson);
                    courseList.remove(lesson);
                    recommendTime++;
                }
                if(recommendTime >= eachKindRecommendNum){
                    break;
                }
            }
        }
        if(creditComposition.get("劳育") == 0.0){
            Collections.shuffle(courseList);//隨机排列課程
            courseListCopy = new ArrayList<>(courseList);
            int recommendTime = 0;
            for(Lesson lesson:courseListCopy){
                if(lesson.get课程号().equals("00372480A")){
                    recommendCourse.add(lesson);
                    courseList.remove(lesson);
                    recommendTime++;
                }
                if(recommendTime >= eachKindRecommendNum){
                    break;
                }
            }
        }
        if(creditComposition.get("美育") == 0.0){
            Collections.shuffle(courseList);//隨机排列課程
            courseListCopy = new ArrayList<>(courseList);
            int recommendTime = 0;
            for(Lesson lesson:courseListCopy){
                if(lesson.get课程号().equals("00302390S")){
                    recommendCourse.add(lesson);
                    courseList.remove(lesson);
                    recommendTime++;
                }
                if(recommendTime >= eachKindRecommendNum){
                    break;
                }
            }
        }
        if(creditComposition.get("阅读") < 1.0){
            Collections.shuffle(courseList);//隨机排列課程
            courseListCopy = new ArrayList<>(courseList);
            int recommendTime = 0;
            for(Lesson lesson:courseListCopy){
                if(lesson.get课程号().startsWith("004")){
                    recommendCourse.add(lesson);
                    courseList.remove(lesson);
                    recommendTime++;
                }
                if(recommendTime >= eachKindRecommendNum){
                    break;
                }
            }
        }
        if(creditComposition.get("通识") < 14.0){
            Collections.shuffle(courseList);//隨机排列課程
            courseListCopy = new ArrayList<>(courseList);
            int recommendTime = 0;
            for(Lesson lesson:courseListCopy){
                if(lesson.get课程号().startsWith("002")|| lesson.get课程号().startsWith("003")|| lesson.get课程号().startsWith("005")|| lesson.get课程号().startsWith("37")|| lesson.get课程号().startsWith("500")){
                    recommendCourse.add(lesson);
                    courseList.remove(lesson);
                    recommendTime++;
                }
                if(recommendTime >= eachKindRecommendNum){
                    break;
                }
            }
        }
        List<String> failedCourse = student.getStudy_situation().getFailed_course();
        courseListCopy = new ArrayList<>(courseList);
        for(Lesson lesson: courseListCopy){
            if(requiredGeneralCourse.contains(lesson.get课程号()) || requiredCoreCourse.contains(lesson.get课程号()) || failedCourse.contains(lesson.get课程号())){
                recommendCourse.add(lesson);
                courseList.remove(lesson);
            }
        }
        if(student.getAdmission_year() >= 2022){
            if(student.getChoose_course_setting().getMajor_intention().length() > 0){
                courseListCopy = new ArrayList<>(courseList);
                List<String> majorAllowIn = this.majorDetail.get(student.getChoose_course_setting().getMajor_intention()).get专业准入();
                for(Lesson lesson: courseListCopy){
                    if(majorAllowIn.contains(lesson.get课程号())){
                        recommendCourse.add(lesson);
                        courseList.remove(lesson);
                    }
                }
            }

        }else{
            if(student.getMajor().equals("软件工程")){
                courseListCopy = new ArrayList<>(courseList);
                for(Lesson lesson: courseListCopy){
                    if(lesson.get课程号().startsWith("250")){
                        recommendCourse.add(lesson);
                        courseList.remove(lesson);
                    }
                }
            }else if(student.getMajor().equals("化学")){
                courseListCopy = new ArrayList<>(courseList);
                for(Lesson lesson: courseListCopy){
                    if(lesson.get课程号().startsWith("130")){
                        recommendCourse.add(lesson);
                        courseList.remove(lesson);
                    }
                }
            }
        }
        if(creditComposition.get("全部") < 150){
            Collections.shuffle(courseList);//隨机排列課程
            recommendCourse.addAll(courseList);
        }
        List<String> rawName = new ArrayList<>();
        List<Lesson> recommendCourseCopy = new ArrayList<>(recommendCourse);
        List<String> avoidDay = student.getChoose_course_setting().getAvoid_day();
        List<String> avoidTime = student.getChoose_course_setting().getAvoid_time();
        for(Lesson lesson : recommendCourseCopy){
            for(Map<String,Object> timeAndPlace : lesson.get时间地点()){
                if(timeAndPlace.get("时间") instanceof String) break;
                LinkedHashMap<String,String> time = (LinkedHashMap<String, String>) timeAndPlace.get("时间");
                if(avoidDay != null && avoidDay.contains(time.get("日"))){
                    recommendCourse.remove(lesson);
                    break;
                }
                if(avoidTime != null && avoidTime.contains(time.get("节"))){
                    recommendCourse.remove(lesson);
                    break;
                }

            }
        }
        for(Lesson lesson: recommendCourse){
            rawName.add(lesson.get课程名());
        }
        return ResponseEntity.ok(recommendCourse);
    }

   public List<Map<String, Object>> transferJsonToList(String path) {
        ObjectMapper objectMapper = new ObjectMapper();
        File file = new File(path);
        try {
            // 读取JSON文件并转换为Map对象
            List<Map<String, Object>> list = objectMapper.readValue(file, List.class);
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public List<Lesson> transferLesson(String path) {
        ObjectMapper objectMapper = new ObjectMapper();
        File file = new File(path);
        try {
            // 读取JSON文件并转换为Map对象
            List<Lesson> list = objectMapper.readValue(file, new TypeReference<List<Lesson>>() {});
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public Map<String, Student> transferStudent(String path) {
        ObjectMapper objectMapper = new ObjectMapper();
        File file = new File(path);
        try {
            // 读取JSON文件并转换为Map对象
            Map<String, Student> map = objectMapper.readValue(file, new TypeReference<Map<String, Student>>() {});
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public Map<String, Major> transferMajor(String path) {
        ObjectMapper objectMapper = new ObjectMapper();
        File file = new File(path);
        try {
            // 读取JSON文件并转换为Map对象
            Map<String, Major> major = objectMapper.readValue(file, new TypeReference<Map<String, Major>>(){});
            return major;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
